#include "server_http.h"
#include "av.h"
#include "cJSON.h"

/*
MHD_Result print_out_key(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
{
  printf ("%s: %s\n", key, value);
  return MHD_YES;
}

MHD_Result  connectionHandler(
    void *cls,
    struct MHD_Connection *connection,
    const char *url,
    const char *method,
    const char *version,
    const char *upload_data,
    long unsigned int *upload_data_size,
    void **con_cls)
{
    printf("Get one request: %s %s %s\n", method, version, url);
    //MHD_get_connection_values (connection, MHD_HEADER_KIND, print_out_key, NULL);
    //const char* body = MHD_lookup_connection_value(connection, MHD_POSTDATA_KIND, NULL);
	const char* onefile = body;
	const char* virname = ScanFile(onefile);
    if (virname == NULL) virname = "";

    char pageBuffer[256];
    int buffLen = sprintf(pageBuffer, "{'status':'ok','result':'%s'}", virname);

    struct MHD_Response *response;
    response = MHD_create_response_from_buffer(buffLen,
        (void*)pageBuffer, MHD_RESPMEM_PERSISTENT);

    if (MHD_add_response_header(response, "Content-Type", "application/json") == MHD_NO) {
        printf("MHD_add_response_header error\n");
        return MHD_NO;
    }
    if (MHD_queue_response(connection, MHD_HTTP_OK, response) == MHD_NO) {
        printf("MHD_queue_response error\n");
        return MHD_NO;
    }
    MHD_destroy_response(response);

    return MHD_YES;
}
*/

const string web_server::on_request (
    const dlib::incoming_things& incoming,
    dlib::outgoing_things& outgoing
)
{
    string res = response(incoming.request_type, incoming.path, incoming.body);
    return res;
}

string getFilenameFromJson(const char* jsonStr)
{
    cJSON* pRoot = cJSON_Parse(jsonStr);
    if (pRoot == NULL) return "";
    cJSON* pFilenameEle = cJSON_GetObjectItem(pRoot, "filename");
    if (pFilenameEle == NULL) return "";
    const char* filename = cJSON_GetStringValue(pFilenameEle);
    string res = filename;
    cJSON_free(pRoot);
    return res;
}

bool urlMatch(const string& path, const char* urlPrefix)
{
    int prefixLen = strlen(urlPrefix);
    if (path == urlPrefix || (strncmp(path.c_str(), urlPrefix, prefixLen) == 0 && path[prefixLen] == '/'))
        return true;
    return false;
}

string web_server::response(const string& request_type, const string& path, const string& body)
{
    printf("Get one request: %s %s\n", request_type.c_str(), path.c_str());
    if (urlMatch(path, "/serverfile"))
    {
        const char* jsonStr = body.c_str();
        string filenameStr = getFilenameFromJson(jsonStr);
        const char* onefile = filenameStr.c_str();
        if (onefile[0] == 0) return "{'status':'error','message':'miss json param: filename'}";
        if (access(onefile, 0) != 0) return "{'status':'error','message':'file not found'}";
        const char* virname = AntiVirus::GetInstance()->ScanFile(onefile);
        if (virname == NULL) virname = "";
        char pageBuffer[256];
        int buffLen = sprintf(pageBuffer, "{'status':'ok','message':'','result':'%s'}", virname);
        return pageBuffer;
    }
    else if (urlMatch(path, "/binary"))
    {
        const char* data = body.c_str();
        int dataLen = body.length();
        char filenameBuf[256];
        int pos = sprintf(filenameBuf, "/tmp/virusscan_");
        struct tm ptr;
        time_t tm = time(0);
        localtime_r(&tm, &ptr);
        strftime(filenameBuf + pos, 256 - pos, "%Y%m%d%H%M%S", &ptr);
        pos += 14;
        filenameBuf[pos++] = '_';
        sprintf(filenameBuf + pos, "%06d", rand() / 1000000);
        FILE* fp = fopen(filenameBuf, "wb");
        fwrite(data, 1, dataLen, fp);
        fclose(fp);

        const char* onefile = filenameBuf;
        const char* virname = AntiVirus::GetInstance()->ScanFile(onefile);
        unlink(onefile);
        if (virname == NULL) virname = "";
        char pageBuffer[256];
        int buffLen = sprintf(pageBuffer, "{'status':'ok','message':'','result':'%s'}", virname);
        return pageBuffer;
    }
    return "{'status':'error','message':'unknown url'}";
}
